package com.gsafety.wellsfort.controller.security;

import com.alibaba.fastjson.JSONObject;
import com.gsafety.wellsfort.annotation.CheckToken;
import com.gsafety.wellsfort.common.constant.IConstant;
import com.gsafety.wellsfort.common.context.LoginContextUtil;
import com.gsafety.wellsfort.common.enums.RedisPrefixEnum;
import com.gsafety.wellsfort.common.util.ApiResponse;
import com.gsafety.wellsfort.common.util.IpUtil;
import com.gsafety.wellsfort.common.util.JwtUtil;
import com.gsafety.wellsfort.common.util.ResultCode;
import com.gsafety.wellsfort.config.CacheManager;
import com.gsafety.wellsfort.domain.dto.ids.AdminIdDTO;
import com.gsafety.wellsfort.domain.dto.login.LoginDTO;
import com.gsafety.wellsfort.domain.dto.secuirty.AdminDto;
import com.gsafety.wellsfort.domain.model.security.Admin;
import com.gsafety.wellsfort.domain.model.security.UserLogin;
import com.gsafety.wellsfort.domain.vo.AdminLoginVO;
import com.gsafety.wellsfort.domain.vo.AdminQueryVO;
import com.gsafety.wellsfort.domain.vo.AdminResultVO;
import com.gsafety.wellsfort.domain.vo.AdminVO;
import com.gsafety.wellsfort.service.security.IAdminService;
import com.gsafety.wellsfort.service.security.IUserLoginService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.xml.transform.Result;
import java.util.List;

@Api(description = "管理员接口")
@RestController
@Slf4j
@RequestMapping("/api/admin")
public class AdminController {

    @Autowired
    private IAdminService adminService;

    @Autowired
    private IUserLoginService userLoginService;

    @Autowired
    private CacheManager cacheManager;

    /**
     * 业务: 操作ip限制一天3次
     *
     * @param loginVO
     * @param request
     * @return
     */
    @ApiOperation(value = "后台忘记密码")
    @CheckToken(value = false)
    @PostMapping("/forgetPassword")
    public ApiResponse forgetPassword(@RequestBody LoginDTO loginDTO, HttpServletRequest request) {
        String captcha = cacheManager.get(loginDTO.getToken());
        if (StringUtils.isEmpty(captcha) || !captcha.equalsIgnoreCase(loginDTO.getCaptcha())) {
            return ApiResponse.error(ResultCode.IMG_CAPTCHA_IS_ERROR);
        }
        UserLogin userLogin = userLoginService.getUserLoginByAccount(loginDTO.getAccount());
        if (userLogin == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        Admin admin = adminService.getByLoginId(userLogin.getId());
        String smsCode = cacheManager.get(RedisPrefixEnum.SMS_CAPTCHA_PREFIX.getPrefix() + admin.getPhone());
        if (StringUtils.isEmpty(smsCode) || !smsCode.equalsIgnoreCase(loginDTO.getSmsCode())) {
            return ApiResponse.error(ResultCode.CAPTCHA_ERROR);
        }
        String count = cacheManager.get(RedisPrefixEnum.IP_OPERATOR_PREFIX.getPrefix() + DigestUtils.md5Hex(IpUtil.getIp(request)));
        if (count == null) {
            cacheManager.set(RedisPrefixEnum.IP_OPERATOR_PREFIX.getPrefix() + DigestUtils.md5Hex(IpUtil.getIp(request)), new String("1"), RedisPrefixEnum.IP_OPERATOR_PREFIX.getExpireTime());
        } else {
            if (Integer.parseInt(count) > 3) {
                return ApiResponse.error(ResultCode.IP_OPERATOR_FREQUENTLY);
            } else {
                cacheManager.set(RedisPrefixEnum.IP_OPERATOR_PREFIX.getPrefix() + DigestUtils.md5Hex(IpUtil.getIp(request)), String.valueOf(Integer.parseInt(count) + 1), RedisPrefixEnum.IP_OPERATOR_PREFIX.getExpireTime());
            }
        }
        if (StringUtils.isEmpty(loginDTO.getPassword())) {
            return ApiResponse.error(ResultCode.ERROR, "新密码不能为空!");
        }
        UserLogin newUserLogin = UserLogin.builder().id(userLogin.getId()).
                password(DigestUtils.md5Hex(loginDTO.getPassword())).
                originalPassword(loginDTO.getPassword()).operator(loginDTO.getAccount()).build();
        //更新登录信息
        if (userLoginService.update(newUserLogin) > 0) {
            return ApiResponse.success("修改密码成功");
        } else {
            return ApiResponse.error();
        }
    }

    /**
     * 菜单列表
     *
     * @return
     */
    @ApiOperation(value = "管理员列表")
    @PostMapping("/list")
    public ApiResponse<List<AdminResultVO>> list(@RequestBody AdminQueryVO query) {
        if (query.getType() == null || query.getType() != 1) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        ApiResponse<List<Admin>> apiResponse = adminService.pageQuery(query);
        return adminService.convertDo2VO(apiResponse);
    }

    @ApiOperation(value = "添加管理员")
    @PostMapping(value = "/add")
    public ApiResponse add(@RequestBody AdminVO adminVO) {
        UserLogin userLogin = userLoginService.getUserLoginByAccount(adminVO.getAccount());
        if (userLogin != null) {
            return ApiResponse.error(ResultCode.ACCOUNT_HAS_EXIST);
        }
        return adminService.add(convertVO2Dto(adminVO));
    }

    @ApiOperation(value = "更新管理员")
    @PostMapping(value = "/update")
    public ApiResponse update(@RequestBody AdminVO adminVO) {
        if (adminService.update(convertVO2Dto(adminVO))) {
            return ApiResponse.success();
        } else {
            return ApiResponse.error();
        }
    }

    @ApiOperation(value = "删除管理员")
    @PostMapping(value = "/delete")
    public ApiResponse delete(@RequestBody AdminIdDTO idDTO) {
        if (adminService.delete(idDTO.getAdminId())) {
            return ApiResponse.success();
        } else {
            return ApiResponse.error();
        }
    }

    @ApiOperation(value = "管理员详情接口")
    @PostMapping(value = "/detail")
    public ApiResponse<AdminLoginVO> detail() {
        Admin admin = adminService.getByLoginId(LoginContextUtil.getUid());
        return ApiResponse.success(convertDo2LoginVO(admin));
    }

    @ApiOperation(value = "快速获取token,后台测试专用")
    @CheckToken(value = false)
    @PostMapping(value = "/getAdminToken")
    public ApiResponse<String> getAdminToken(String phone) {
        UserLogin userLogin = userLoginService.getUserLoginByAccount(phone);
        // 成功登录
        String token = JwtUtil.createJWT(8 * 60 * 60 * 1000, userLogin);
        cacheManager.setHashKey(RedisPrefixEnum.ACCOUNT_TOKEN_UNIQUE.getPrefix(), userLogin.getAccount(), token);
        JSONObject result = new JSONObject();
        result.put(IConstant.TOKEN, token);
        return ApiResponse.success(result);
    }

    /**
     * @param adminVO
     * @return
     */
    private AdminDto convertVO2Dto(AdminVO adminVO) {
        AdminDto adminDto = new AdminDto();
        BeanUtils.copyProperties(adminVO, adminDto);
        return adminDto;
    }

    /**
     * @param admin
     * @return
     */
    private AdminLoginVO convertDo2LoginVO(Admin admin) {
        AdminLoginVO loginVO = new AdminLoginVO();
        BeanUtils.copyProperties(admin, loginVO);
        loginVO.setAccount(LoginContextUtil.getAccount());
        loginVO.setIsPlatform(admin.getSchoolId() == 1 ? true : false);
        return loginVO;
    }
}
